#include "drv_encoder.h"

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>

#include "inc/hw_memmap.h"

#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_qei.h"
#include "inc/hw_ints.h"
#include "inc/hw_uart.h"

#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/qei.h"
#include "driverlib/interrupt.h"
#include "driverlib/uart.h"

#define PHA_PERIPH_L SYSCTL_PERIPH_GPIOC // A相
#define PHB_PERIPH_L SYSCTL_PERIPH_GPIOC // B相
#define PHA_BASE_L GPIO_PORTC_BASE
#define PHB_BASE_L GPIO_PORTC_BASE
#define PHA_PIN_L GPIO_PIN_5
#define PHB_PIN_L GPIO_PIN_6
#define PHA_PINCONF_L GPIO_PC5_PHA1
#define PHB_PINCONF_L GPIO_PC6_PHB1
#define QEI_PERIPH_L SYSCTL_PERIPH_QEI1 //使用QEI1外设
#define QEI_BASE_L QEI1_BASE

#define PHA_PERIPH_R SYSCTL_PERIPH_GPIOD // A相
#define PHB_PERIPH_R SYSCTL_PERIPH_GPIOD // B相
#define PHA_BASE_R GPIO_PORTD_BASE
#define PHB_BASE_R GPIO_PORTD_BASE
#define PHA_PIN_R GPIO_PIN_6
#define PHB_PIN_R GPIO_PIN_7
#define PHA_PINCONF_R GPIO_PD6_PHA0
#define PHB_PINCONF_R GPIO_PD7_PHB0
#define QEI_PERIPH_R SYSCTL_PERIPH_QEI0 //使用QEI0外设
#define QEI_BASE_R QEI0_BASE

void ist_encoder_init(void)
{
    // GPIO初始化
    SysCtlPeripheralEnable(PHA_PERIPH_L);
    while (!SysCtlPeripheralReady(PHA_PERIPH_L))
        ;

    SysCtlPeripheralEnable(PHA_PERIPH_R);
    while (!SysCtlPeripheralReady(PHA_PERIPH_R))
        ;

    SysCtlPeripheralEnable(PHB_PERIPH_L);
    while (!SysCtlPeripheralReady(PHB_PERIPH_L))
        ;

    SysCtlPeripheralEnable(PHB_PERIPH_R);
    while (!SysCtlPeripheralReady(PHB_PERIPH_R))
        ;
    // QEI初始化
    SysCtlPeripheralEnable(QEI_PERIPH_L);
    while (!SysCtlPeripheralReady(QEI_PERIPH_L))
        ;

    SysCtlPeripheralEnable(QEI_PERIPH_R);
    while (!SysCtlPeripheralReady(QEI_PERIPH_R))
        ;
    //将QEI分配到相应管脚
    GPIOPinConfigure(PHA_PINCONF_L);
    GPIOPinConfigure(PHB_PINCONF_L);
    GPIOPinTypeQEI(PHA_BASE_L, PHA_PIN_L);
    GPIOPinTypeQEI(PHB_BASE_L, PHB_PIN_L);

    // 解锁引脚
    HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |= GPIO_PIN_7;

    GPIOPinConfigure(PHA_PINCONF_R);
    GPIOPinConfigure(PHB_PINCONF_R);
    GPIOPinTypeQEI(PHA_BASE_R, PHA_PIN_R);
    GPIOPinTypeQEI(PHB_BASE_R, PHB_PIN_R);

    //配置QEI
    QEIConfigure(QEI_BASE_L, QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_NO_RESET | QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP, 1324);
    QEIConfigure(QEI_BASE_R, QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_NO_RESET | QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP, 1324);

    QEIFilterConfigure(QEI_BASE_L, QEI_FILTCNT_2);
    QEIFilterConfigure(QEI_BASE_R, QEI_FILTCNT_2);

    QEIEnable(QEI_BASE_L);
    QEIEnable(QEI_BASE_R);
}

void ist_encoder_reset(void)
{
    QEIPositionSet(QEI_BASE_L, 0);
    QEIPositionSet(QEI_BASE_R, 0);
}

void ist_encoder_get(int *left, int *right)
{
    *left = (short)QEIPositionGet(QEI_BASE_L);
    *right = (short)QEIPositionGet(QEI_BASE_R);
}
